import $store from '@/store/index'
import BLEconnect from './ble-connect'
import sendCommend from '@/static/js/ble-handler/send-commend'
import TimerDelay from '../timer-delay'

// 读取状态 
// 0: 初始化
// 1.发送读取配置命令
// 2.接收到ACK,等待config数据
// 3.数据接收完成,发送ACK
// 4.发送ACK成功，发送读取记录命令
// 5.接收ACK，等待data数据
// 6.一次记录包接收完成
let readState = 0 // 读取状态
let dataState = 0 // 读取数据状态
let Delay = null // 超时方法
let timeOut = 0 // 超时时长
let Connect = null // 蓝牙
let writeId = '' // 写入ID
let datalength = 0 // 数据长度
let postion = 0 // 数据位置
let moreData = 0 // 更多数据
let complete = false // 是否读取完成
let dataGet = new Uint8Array(2100)
let recNum = 0
let detailsData = {} // 详细数据
let cloumnArr = [] // 详细列表数据存储
let resultData = {}

// 写入指令
function writeCommend(cmd) {
    Delay.reset(timeOut) // 重置超时
    const buffer = sendCommend(cmd, dataGet)
    Connect.writeValue(buffer, writeId).then(res => {
        if (cmd == 4) {
            console.log('软件停止记录')
        }
        if (cmd == 3 || cmd == 31) {
            if (readState == 3) {
                readState = 4
                setTimeout(() => {
                    writeCommend(2)
                }, 200)
            }
            if (readState == 6 && complete) {
                readState = 0 // 重置
            }
        }
    })
}

// 监听广播
function onBLECharacteristicValueChange() {
    uni.onBLECharacteristicValueChange(res => {
        let bufrx = new Uint8Array(res.value)
        switch (readState) {
            case 1:
                if (bufrx[0] == 0xCF && ((bufrx[1] & 0x10) == 0x10)) {
                    readState = 2
                    dataState = 0
                }
                break
            case 2:
                dataPackage(bufrx)
                if (readState == 3) {
                    writeCommend(31)
                }
                break
            case 3:
                break
            case 4:
                if ((bufrx[0] == 0xCF) && ((bufrx[1] & 0x10) == 0x10)) {
                    readState = 5
                    dataState = 0
                }
                break
            case 5:
                dataPackage(bufrx)
                if (readState == 6) {
                    writeCommend(3)
                }
                if (readState == 7) {
                    readState = 5
                    writeCommend(3)
                }
                break
            case 5:
                break
            case 7:
                break
        }
    })
}

// 设置读取数据
function dataPackage(value) {
    switch (dataState) {
        case 0:
            if (value[0] == 0xCf) {
                postion = 0
                datalength = value[2] * 256 + value[3] + 8
                dataGet.set(value, postion)
                postion += value.length
                dataState = 1
            }
            break
        case 1:
            dataGet.set(value, postion)
            postion += value.length
            // 判断是否接收完成
            if (readState == 2) {
                if ((postion == datalength) || ((postion == (datalength - 12)) && ((postion[16] & 0x08) == 0x08))) {
                    dataState = 0 // 重置数据记录状态
                    parseConfig(dataGet.subarray(0, postion)) // 解析数据
                    readState = 3
                    postion = 0 // 重置位置
                }
            }
            // 接收温度数据完成
            if (readState == 5) {
                // console.log('接收数据：', value)
                if (postion == datalength) {
                    dataState = 0
                    // 转换温度数据
                    parseData(dataGet.subarray(0, postion))
                    if (!moreData) {
                        // 没有更多的数据了
                        setDetailsData()
                        readState = 6
                        postion = 0
                    } else {
                        readState = 7
                        postion = 0
                    }
                }
            }
            break
    }
}

// 解析数据
function parseData(buffer) {
    const viewData = new DataView(buffer.buffer)
    let num = viewData.getInt16(16)
    moreData = buffer[13]

    for (let i = 0; i < num; i++) {
        let temp1 = viewData.getInt16(18 + i * 2)
        let temp2 = null
        let temp3 = null
        let temp4 = null
        if (temp1 >= 0) {
            temp2 = temp1 % 10
            temp3 = (temp1 - temp2) / 100
        } else {
            temp4 = (temp1 * -1) % 10
            temp3 = ((temp1 * -1 - temp4) * -1) / 100
        }
        cloumnArr.push(temp3.toFixed(1))
    }
}

// 查询码
const customCheckID = (buffer) => {
    let id = ''
    if (buffer[44] == 6) {
        for (let i = 0; i < 6; i++) {
            id += String.fromCharCode(buffer[45 + i])
        }
    }
    return id
}
// 客户姓名
const customName = (buffer, configoff, viewData) => {
    let name = ''
    if (buffer[configoff] != 0) {
        for (let i = 0; i < buffer[configoff]; i += 2) {
            name += String.fromCharCode(viewData.getInt16(configoff + 1 + i, true))
        }
    }

    return name
}

// setTrackID
const setTrackID = (configoff, buffer) => {
    let id = ''
    if (buffer[configoff] != 0) {
        for (let i = 0; i < buffer[configoff]; i++) {
            id += String.fromCharCode(buffer[configoff + 1 + i])
        }
    }

    return id
}

// BoxID
const setBoxId = (configoff, buffer) => {
    let id = ''
    if (buffer[configoff] != 0) {
        for (let i = 0; i < buffer[configoff]; i++) {
            id += String.fromCharCode(buffer[configoff + 1 + i])
        }
    }
    return id
}

// setNoteMark
const setNoteMark = (buffer, configoff, viewData) => {
    let result = ''
    if (buffer[configoff] != 0) {
        for (let i = 0; i < buffer[configoff]; i += 2) {
            result += String.fromCharCode(viewData.getInt16(configoff + 1 + i, true))
        }
    }
    return result
}

// 解析配置
function parseConfig(buffer) {
    recNum = buffer[17] * 256 + buffer[18]
    let viewData = new DataView(buffer.buffer)
    let timeZone = viewData.getInt8(34)

    resultData.tagRecNum = recNum // 记录总数量
    resultData.tagBat = buffer[19] // 电量
    resultData.timezone = timeZone > 4 ? -1 * (timeZone - 4) : timeZone + 8 // 时区
    resultData.startTime = (Date.UTC(buffer[20] + 2000, buffer[21] - 1, buffer[22], buffer[23], buffer[24], buffer[25]) - Date.UTC(2000, 0, 1)) / 1000
    resultData.maxLimitedTemp = viewData.getInt16(26) // 温度上限
    resultData.minLimitedTemp = viewData.getInt16(28) // 温度下限
    resultData.recInterval = viewData.getInt16(30) // 记录间隔
    resultData.recDelay = viewData.getInt16(32) // 延迟启动
    resultData.StartMode = ((buffer[14] & 0x10) == 0x10) ? 1 : 0 //是否是定时启动
    resultData.StopMode = ((buffer[14] & 0x01) == 0x01) ? 1 : 0 //是否是软件停止
    resultData.customCheckID = customCheckID(buffer)
    let configoff = 44 + 7
    configoff += buffer[configoff] + 1 // 授权码
    resultData.customName = customName(buffer, configoff, viewData)
    configoff += buffer[configoff] + 1
    resultData.trackID = setTrackID(configoff, buffer)
    configoff += buffer[configoff] + 1
    resultData.boxID = setBoxId(configoff, buffer)
    configoff += buffer[configoff] + 1
    resultData.noteMark = setNoteMark(buffer, configoff, viewData)
    setDetailsConfig(resultData)
}

// 设置详细数据中的配置
function setDetailsConfig(data) {
    Object.assign(detailsData, {
        notes: data.noteMark,
        trackID: data.trackID,
        boxID: data.boxID,
        downTemperature: data.maxLimitedTemp,
        upTemperature: data.minLimitedTemp,
        interval1: data.recInterval,
        recDelay: data.recDelay,
        avgTemperature: '',
        qty: data.tagRecNum,
        startRecTime: data.startTime
    })
}

// 求平均值
function average(arr) {
    var sum = eval(arr.join("+"));
    return ~~(sum / arr.length * 100) / 100;
}
// 设置详情数据
function setDetailsData() {
    console.log('读取完毕,设置详情数据')
    const [...arr] = cloumnArr
    detailsData.startToReadTemp = arr
    detailsData.maxTemperature = Math.max(...arr) // 最大温度
    detailsData.minTemperature = Math.min(...arr) // 最小温度
    detailsData.avgTemperature = average(arr) // 平均温度
    // 结束时间
    cloumnArr = [] // 清除原数据
    uni.hideLoading()    
    uni.navigateTo({
        url: `/pages/read-details/read-details?id=${detailsData.mid}`,
        animationType: 'slide-in-right',
        success: res => {
            uni.$emit('setDetailsData', detailsData)
        }
    })
    // 读取完成，清除定时器并断开蓝牙
    console.log('**************数据', detailsData)
    uni.hideLoading()
    Connect.disconnect() // 断开
    Delay.stop() // 关闭超时
}

// 重试
function timeOutMessage() {
    uni.hideLoading()
    Connect.disconnect() // 断开
    Delay.stop() // 关闭超时
    uni.showToast({
        icon: 'none',
        title: '读取超时，请重试'
    })
}

function connectInt(data) {
    Connect = new BLEconnect(data.deviceId) // 初始化
    Connect.getCharacteristicValue().then(res => {
        Delay.reset(timeOut) // 重置超时
        // 获取广播特征值
        Connect.getNotifyValue().then(nid => {
            Delay.reset(timeOut) // 重置超时
            // 开启广播
            Connect.openNotify(nid).then(_ => {
                Delay.reset(timeOut) // 重置超时
                // 获取写入特征值
                Connect.getWriteValue().then(wid => {
                    Delay.reset(timeOut) // 重置超时
                    writeId = wid
                    readState = 1 // 设置为1，收到指令后开始读取
                    setTimeout(() => {
                        onBLECharacteristicValueChange()
                        writeCommend(1)
                    }, 200)
                })
            })
        })
    })
}

export default function(data) {
    detailsData = {
        deviceId: data.deviceId,
        mid: data.mid,
        nowTemplate: data.nowTemplate
    }
    uni.showLoading({
        title: '读取中',
        mask: true
    })
    // 开启超时计时
    if (!Delay) {
        timeOut = $store.state['global-config'].readTimeOut * 1000
        Delay = new TimerDelay(timeOutMessage, timeOut)
    } else {
        Delay.start()
    }

    // 初始化
    connectInt(data)
}